﻿using System.Linq;
using Htse.Blue.Data;
using Htse.Blue.Logic.Validation;
using Htse.Blue.Models;
using System.Linq.Dynamic;
using System.Text.RegularExpressions;

namespace Htse.Blue.Logic
{
	public class UmpireService :
		ServiceBase<Umpire, int, IUmpireRepository>,
		IUmpireService
	{
		public UmpireService(IValidationDictionary<Umpire> validationDictionary)
			: base(validationDictionary, new UmpireRepository())
		{
		}

		public UmpireService(
			IValidationDictionary<Umpire> validationDictionary,
			IUmpireRepository umpireRepository)
			: base(validationDictionary, umpireRepository)
		{
		}

		#region IUmpireService Members

		public bool Update(Umpire umpireToEdit, string originalAccountName)
		{
			this.ValidateAlways(umpireToEdit, ValidationDictionary);

			this.ValidateOnUpdate(umpireToEdit, originalAccountName);

			if (!ValidationDictionary.IsValid)
			{
				return false;
			}

			repository.SaveOrUpdate(umpireToEdit);

			return true;
		}

		public Umpire GetByAccountName(string accountName)
		{
			return repository.GetSingle(u => u.AccountName == accountName);
		}

		#endregion

		protected override void ValidateAlways(
			Umpire entityToValidate,
			IValidationDictionary<Umpire> validationDictionary)
		{
			if (entityToValidate.FirstName.Trim().Length == 0)
			{
				validationDictionary.AddError(u => u.FirstName, "Il nome è obbligatorio");
			}
			if (entityToValidate.LastName.Trim().Length == 0)
			{
				validationDictionary.AddError(u => u.LastName, "Il cognome è obbligatorio");
			}
			if (entityToValidate.Email.Length == 0)
			{
				validationDictionary.AddError(u => u.Email, "L'indirizzo email è obbligatorio");
			}
			if (entityToValidate.Email.Length > 0 && !(entityToValidate.Email.ValidateAsEmail()))
			{
				validationDictionary.AddError(u => u.Email, "L'indirizzo email è sbagliato");
			}
			if (string.IsNullOrEmpty(entityToValidate.CardNumber))
			{
				validationDictionary.AddError(u => u.CardNumber, "Il numero di tessera è obbligatorio");
			}
			if ((entityToValidate.CardNumber.Length != 5) || (!Regex.IsMatch(entityToValidate.CardNumber, @"\d{5}")))
			{
				validationDictionary.AddError(u => u.CardNumber, "Il numero di tessera deve contenere esattamente 5 cifre");
			}
			if (!string.IsNullOrEmpty(entityToValidate.Phone) && !(entityToValidate.Phone.ValidateAsPhone()))
			{
				validationDictionary.AddError(u => u.Phone, "Il numero telefono non è in un formato corretto");
			}
			if (entityToValidate.CityId == 0)
			{
				validationDictionary.AddError(u => u.City, "Il comune di residenza è obbligatorio");
			}
			if (string.IsNullOrEmpty(entityToValidate.AccountName))
			{
				validationDictionary.AddError(u => u.AccountName, "E' obbligatorio selezionare un account");
			}
		}

		protected override void ValidateOnlyOnCreate(
			Umpire entityToValidate,
			IValidationDictionary<Umpire> validationDictionary)
		{
			if (
				repository
				.GetAll()
				.Select(u => u.AccountName)
				.AsEnumerable()
				.Any(a => string.Equals(
					a,
					entityToValidate.AccountName.ToLower(),
					System.StringComparison.InvariantCultureIgnoreCase)))
			{
				validationDictionary.AddError("AccountName", "L'account selezionato è già stato usato per un altro utente");
			}
		}

		private void ValidateOnUpdate(Umpire umpireToEdit, string originalAccountName)
		{
			if (
				repository
				.GetAll()
				.Select(u => u.AccountName)
				.AsEnumerable()
				.Any(a => string.Equals(
					a,
					umpireToEdit.AccountName.ToLower(),
					System.StringComparison.InvariantCultureIgnoreCase)) &&
				!(originalAccountName == umpireToEdit.AccountName)
				)
			{
				ValidationDictionary.AddError("AccountName", "L'account selezionato è già stato usato per un altro utente");
			}
		}
	}
}
